home *** CD-ROM | disk | FTP | other *** search
/ STraTOS 1997 April & May / STraTOS 1 - 1997 April & May.iso / CD01 / INTERNET / SITES / LITTLE / BMSRC.ZIP / MEMORY.S < prev    next >
Encoding:
Text File  |  1996-11-23  |  29.7 KB  |  911 lines

  1. *=======================================================*
  2. *    Memory module: latest update 29/02/96        *
  3. *=======================================================*
  4. *    Dynamic triple-linked block manager        *
  5. *=======================================================*
  6. *    Auto-defrag on block deallocation        *
  7. *=======================================================*
  8.  
  9. none            =    -1
  10.  
  11. os_st_reserve        =    16*1024
  12. os_tt_reserve        =    16*1024
  13. shard_size        =    4096
  14.  
  15. malloc_limit        =    16
  16. chunk_limit        =    1024
  17.  
  18.             rsreset
  19. malloc_base        rs.l    1
  20. malloc_size        rs.l    1
  21. malloc_slen        rs.b    0
  22.  
  23.             rsreset
  24. chunk_base        rs.l    1
  25. chunk_size        rs.l    1
  26. chunk_slot        rs.l    1
  27. chunk_lf        rs.b    1
  28. chunk_rf        rs.b    1
  29. chunk_flags        rs.w    1
  30. chunk_ln        rs.l    1
  31. chunk_rn        rs.l    1
  32. chunk_slen        rs.b    0
  33.  
  34.             rsreset
  35. used_chunks        rs.w    1
  36. free_chunks        rs.w    1
  37. total_chunks        rs.w    1
  38. system_chunks        rs.w    1
  39. used_array        rs.l    1
  40. free_array        rs.l    1
  41. chunk_array        rs.l    1
  42. system_array        rs.l    1
  43. dummy_lslot        rs.l    1
  44. dummy_rslot        rs.l    1
  45. dummy_lchunk        rs.b    chunk_slen
  46. dummy_rchunk        rs.b    chunk_slen
  47. pool_slen        rs.b    0
  48.  
  49. cf_used_bit        =    0
  50. cf_break_bit        =    5
  51. cf_used            =    1<<cf_used_bit
  52. cf_break        =    1<<cf_break_bit
  53.  
  54. block_hashbits        =    12
  55.  
  56. *-------------------------------------------------------*
  57. init_block_manager:
  58. *-------------------------------------------------------*
  59.     Mxalloc        #os_st_reserve,#STRAM_only
  60.     move.l        d0,os_st_reserve_ptr
  61.     Mxalloc        #os_tt_reserve,#VRAM_only
  62.     move.l        d0,os_tt_reserve_ptr
  63. *-------------------------------------------------------*
  64. *    Initialise STRAM memory pool            *
  65. *-------------------------------------------------------*
  66.     lea        st_memory_pool,a6
  67.     move.l        #st_used_array_space,used_array(a6)
  68.     move.l        #st_free_array_space,free_array(a6)
  69.     move.l        #st_chunk_array_space,chunk_array(a6)
  70.     move.l        #st_system_array_space,system_array(a6)
  71.     clr.w        used_chunks(a6)
  72.     clr.w        free_chunks(a6)
  73.     clr.w        total_chunks(a6)
  74.     clr.w        system_chunks(a6)
  75.     move.w        #STRAM_only,ram_type
  76.     bsr        claim_memory
  77.     bsr        join_mallocs
  78.     bsr        init_chunks
  79. *-------------------------------------------------------*
  80. *    Initialise TTRAM memory pool            *
  81. *-------------------------------------------------------*
  82.     lea        tt_memory_pool,a6
  83.     move.l        #tt_used_array_space,used_array(a6)
  84.     move.l        #tt_free_array_space,free_array(a6)
  85.     move.l        #tt_chunk_array_space,chunk_array(a6)
  86.     move.l        #tt_system_array_space,system_array(a6)
  87.     clr.w        used_chunks(a6)
  88.     clr.w        free_chunks(a6)
  89.     clr.w        total_chunks(a6)
  90.     clr.w        system_chunks(a6)
  91.     move.w        #VRAM_only,ram_type
  92.     bsr        claim_memory
  93.     bsr        join_mallocs
  94.     bsr        init_chunks
  95. *-------------------------------------------------------*
  96.     Mfree        os_st_reserve_ptr
  97.     move.l        os_tt_reserve_ptr,d0
  98.     ble.s        .done
  99.     Mfree        d0
  100. *-------------------------------------------------------*
  101. .done:    rts
  102.  
  103. *-------------------------------------------------------*
  104. find_largest_block:
  105. *-------------------------------------------------------*
  106.     movem.l        d1-a6,-(sp)
  107. *-------------------------------------------------------*
  108.     moveq        #0,d0
  109.     and.w        #4-1,d1
  110.     jmp        ([.type.w,pc,d1.w*4])
  111. *-------------------------------------------------------*
  112. .type:    dc.l        .stram_only
  113.     dc.l        .ttram_only
  114.     dc.l        .stram_preferred
  115.     dc.l        .ttram_preferred
  116. *-------------------------------------------------------*
  117. .ttram_preferred:
  118. .stram_preferred:
  119. *-------------------------------------------------------*
  120.     lea        tt_memory_pool,a6
  121.     bsr        internal_find_largest
  122. *-------------------------------------------------------*
  123. .stram_only:
  124. *-------------------------------------------------------*
  125.     lea        st_memory_pool,a6
  126.     bsr        internal_find_largest
  127.     bra.s        .allocate_done
  128. *-------------------------------------------------------*
  129. .ttram_only:
  130. *-------------------------------------------------------*
  131.     lea        tt_memory_pool,a6
  132.     bsr        internal_find_largest
  133. *-------------------------------------------------------*
  134. .allocate_done:
  135. *-------------------------------------------------------*
  136.     movem.l        (sp)+,d1-a6
  137.     rts
  138.  
  139. *-------------------------------------------------------*
  140. internal_find_largest:
  141. *-------------------------------------------------------*
  142.     move.l        free_array(a6),a1
  143.     move.w        free_chunks(a6),d6
  144.     lea        (a1,d6.w*4),a1
  145.     bra.s        .loop_start
  146. *-------------------------------------------------------*
  147. .size_loop:
  148. *-------------------------------------------------------*
  149.     move.l        -(a1),a4
  150.     cmp.l        chunk_size(a4),d0
  151.     bpl.s        .loop_start
  152. *-------------------------------------------------------*
  153. *    Block is larger - record size            *
  154. *-------------------------------------------------------*
  155.     move.l        chunk_size(a4),d0
  156. *-------------------------------------------------------*
  157. .loop_start:
  158. *-------------------------------------------------------*
  159.     dbra        d6,.size_loop
  160.     rts
  161.  
  162. *-------------------------------------------------------*
  163. allocate_chunk:
  164. *-------------------------------------------------------*
  165. ;    cmp.l        #-1,d0
  166. ;    beq        find_largest_block
  167. *-------------------------------------------------------*
  168.     movem.l        d1-a6,-(sp)
  169.     move.l        d0,-(sp)
  170. *-------------------------------------------------------*
  171.     and.w        #4-1,d1
  172.     jmp        ([.type.w,pc,d1.w*4])
  173. *-------------------------------------------------------*
  174. .type:    dc.l        .stram_only
  175.     dc.l        .ttram_only
  176.     dc.l        .stram_preferred
  177.     dc.l        .ttram_preferred
  178. *-------------------------------------------------------*
  179. .stram_only:
  180. *-------------------------------------------------------*
  181.     lea        st_memory_pool,a6
  182.     bsr        internal_allocate
  183.     bra.s        .allocate_done
  184. *-------------------------------------------------------*
  185. .ttram_only:
  186. *-------------------------------------------------------*
  187.     lea        tt_memory_pool,a6
  188.     bsr        internal_allocate
  189.     bra.s        .allocate_done
  190. *-------------------------------------------------------*
  191. .stram_preferred:
  192. *-------------------------------------------------------*
  193.     lea        st_memory_pool,a6
  194.     bsr        internal_allocate
  195.     tst.l        d0
  196.     bne.s        .allocate_done
  197.     move.l        (sp),d0
  198.     lea        tt_memory_pool,a6
  199.     bsr        internal_allocate
  200.     bra.s        .allocate_done
  201. *-------------------------------------------------------*
  202. .ttram_preferred:
  203. *-------------------------------------------------------*
  204.     lea        tt_memory_pool,a6
  205.     bsr        internal_allocate
  206.     tst.l        d0
  207.     bne.s        .allocate_done
  208.     move.l        (sp),d0
  209.     lea        st_memory_pool,a6
  210.     bsr        internal_allocate
  211. *-------------------------------------------------------*
  212. .allocate_done:
  213. *-------------------------------------------------------*
  214.     addq.l        #4,sp
  215.     movem.l        (sp)+,d1-a6
  216.     rts
  217.  
  218. *-------------------------------------------------------*
  219. internal_allocate:
  220. *-------------------------------------------------------*
  221. *    Check limit                    *
  222. *-------------------------------------------------------*
  223.     cmp.w        #chunk_limit,used_chunks(a6)
  224.     beq        .alloc_fail
  225. *-------------------------------------------------------*
  226. *    Round up block length to 4 bytes        *
  227. *-------------------------------------------------------*
  228.     addq.l        #4-1,d0
  229.     and.b        #-4,d0
  230. *-------------------------------------------------------*
  231. *    Find suitable block to claim / split        *
  232. *-------------------------------------------------------*
  233.     move.l        free_array(a6),a1
  234.     move.w        free_chunks(a6),d6
  235.     lea        (a1,d6.w*4),a1
  236.     bra.s        .loop_start
  237. *-------------------------------------------------------*
  238. .size_loop:
  239. *-------------------------------------------------------*
  240.     move.l        -(a1),a4
  241.     cmp.l        chunk_size(a4),d0
  242.     ble.s        .alloc_chunk
  243. *-------------------------------------------------------*
  244. .loop_start:
  245. *-------------------------------------------------------*
  246.     dbra        d6,.size_loop
  247. *-------------------------------------------------------*
  248. .alloc_fail:
  249. *-------------------------------------------------------*
  250.     moveq        #0,d0
  251.     bra        .exit
  252. *-------------------------------------------------------*
  253. .alloc_chunk:
  254. *-------------------------------------------------------*
  255.     bmi.s        .split_chunk
  256. *-------------------------------------------------------*
  257. .keep_chunk:
  258. *-------------------------------------------------------*
  259. *    Allocate entire chunk as used            *
  260. *-------------------------------------------------------*
  261.     move.l        chunk_size(a4),d0
  262. *-------------------------------------------------------*
  263.     move.w        free_chunks(a6),d5
  264.     subq.w        #1,d5
  265.     move.w        d5,free_chunks(a6)
  266. *-------------------------------------------------------*
  267. *    Seal gap in list using last entry        *
  268. *-------------------------------------------------------*
  269.     move.l        free_array(a6),a3
  270.     move.l        (a3,d5.w*4),a2
  271.     clr.l        (a3,d5.w*4)
  272.     bra        .skip_split
  273. *-------------------------------------------------------*
  274. .split_chunk:
  275. *-------------------------------------------------------*
  276. *    Eliminate unwanted shards            *
  277. *-------------------------------------------------------*
  278.     move.l        chunk_size(a4),d5
  279.     sub.l        d0,d5
  280.     cmp.l        #shard_size,d5
  281.     bmi.s        .keep_chunk
  282. *-------------------------------------------------------*
  283.     cmp.w        #chunk_limit,total_chunks(a6)
  284.     beq        .alloc_fail
  285. *-------------------------------------------------------*
  286. *    Shrink original chunk to required size        *
  287. *-------------------------------------------------------*
  288. ;    move.l        d0,grabbed
  289.     move.l        chunk_size(a4),d1
  290.     move.l        d0,chunk_size(a4)
  291.     sub.l        d0,d1
  292. *-------------------------------------------------------*
  293. *    Calculate new chunk's base address        *
  294. *-------------------------------------------------------*
  295.     add.l        chunk_base(a4),d0
  296. *-------------------------------------------------------*
  297. *    Create new chunk                *
  298. *-------------------------------------------------------*
  299.     move.w        total_chunks(a6),d2
  300.     addq.w        #1,total_chunks(a6)
  301.     move.l        chunk_array(a6),a2    
  302.     mulu.w        #chunk_slen,d2
  303.     add.l        d2,a2
  304.     move.l        d0,chunk_base(a2)
  305.     move.l        d1,chunk_size(a2)
  306. *-------------------------------------------------------*
  307. *    Break links & insert new (free) chunk        *
  308. *-------------------------------------------------------*
  309.     move.l        chunk_rn(a4),a5
  310.     move.l        a4,chunk_ln(a2)
  311.     move.l        a5,chunk_rn(a2)
  312.     move.l        a2,chunk_rn(a4)    
  313.     move.l        a2,chunk_ln(a5)    
  314. *-------------------------------------------------------*
  315. *    Maintain chunk flags                *
  316. *-------------------------------------------------------*
  317.     move.b        chunk_rf(a4),chunk_rf(a2)
  318.     moveq        #0,d0
  319.     move.b        d0,chunk_lf(a2)
  320.     move.b        d0,chunk_rf(a4)
  321. *-------------------------------------------------------*
  322. .skip_split:
  323. *-------------------------------------------------------*
  324. *    Replace gap in free array & relocate        *
  325. *-------------------------------------------------------*
  326.     move.l        a2,(a1)
  327.     move.l        a1,chunk_slot(a2)
  328. *-------------------------------------------------------*
  329. *    Generate hash index for chunk address        *
  330. *-------------------------------------------------------*
  331.     move.l        chunk_base(a4),d0
  332.     move.l        used_array(a6),a2
  333.     bsr        hash_address    
  334. *-------------------------------------------------------*
  335. *    Double-link chunk with hashed slot        * 
  336. *-------------------------------------------------------*
  337.     lea        (a2,d2.w*4),a3
  338.     move.l        a4,(a3)
  339.     move.l        a3,chunk_slot(a4)
  340.     addq.w        #1,used_chunks(a6)
  341. *-------------------------------------------------------*
  342. *    Flag chunk as 'used' to neighbours        *
  343. *-------------------------------------------------------*
  344.     move.l        chunk_ln(a4),a3
  345.     move.l        chunk_rn(a4),a5
  346.     moveq        #cf_used,d2
  347.     or.b        d2,chunk_rf(a3)
  348.     or.b        d2,chunk_lf(a5)
  349. *-------------------------------------------------------*
  350. .exit:    rts
  351.  
  352. *-------------------------------------------------------*
  353. hash_address:
  354. *-------------------------------------------------------*
  355. *    Hash chunk address                *
  356. *-------------------------------------------------------*
  357.     move.l        d0,d2
  358.     moveq        #block_hashbits,d3
  359.     lsr.l        d3,d2
  360. *-------------------------------------------------------*
  361. *    Search for free hash slot            *
  362. *-------------------------------------------------------*
  363. .search_slot:
  364. *-------------------------------------------------------*
  365.     and.w        #chunk_limit-1,d2
  366.     tst.l        (a2,d2.w*4)
  367.     beq.s        .free_slot
  368.     addq.w        #1,d2
  369.     bra.s        .search_slot
  370. *-------------------------------------------------------*
  371. .free_slot:
  372. *-------------------------------------------------------*
  373.     rts
  374.  
  375. *-------------------------------------------------------*
  376. deallocate_chunk:
  377. *-------------------------------------------------------*
  378.     movem.l        d1-a6,-(sp)
  379. *-------------------------------------------------------*
  380.     push.l        d0
  381.     lea        tt_memory_pool,a6
  382.     bsr        internal_deallocate
  383.     pop.l        d1
  384.     tst.l        d0
  385.     beq.s        .deallocate_done
  386.     move.l        d1,d0
  387.     lea        st_memory_pool,a6
  388.     bsr        internal_deallocate
  389. *-------------------------------------------------------*
  390. .deallocate_done
  391. *-------------------------------------------------------*
  392.     movem.l        (sp)+,d1-a6
  393. *-------------------------------------------------------*
  394.     rts
  395.     
  396. *-------------------------------------------------------*
  397. internal_deallocate:
  398. *-------------------------------------------------------*
  399. *    Hash chunk address                *
  400. *-------------------------------------------------------*
  401.     move.l        d0,d2
  402.     moveq        #block_hashbits,d3
  403.     lsr.l        d3,d2
  404.     move.l        used_array(a6),a2
  405. *-------------------------------------------------------*
  406. *    Search hash table until none left        *
  407. *-------------------------------------------------------*
  408. search_slot:
  409. *-------------------------------------------------------*
  410.     and.w        #chunk_limit-1,d2
  411.     move.l        (a2,d2.w*4),d3
  412.     beq.s        fail_dealloc
  413. *-------------------------------------------------------*
  414. check_handle:
  415. *-------------------------------------------------------*
  416.     move.l        d3,a3
  417.     cmp.l        chunk_base(a3),d0
  418.     beq.s        found_slot
  419. *-------------------------------------------------------*
  420. advance_check:
  421. *-------------------------------------------------------*
  422.     addq.w        #1,d2
  423.     bra.s        search_slot
  424. *-------------------------------------------------------*
  425. fail_dealloc:
  426. *-------------------------------------------------------*
  427.     moveq        #-1,d0
  428.     bra        exit
  429. *-------------------------------------------------------*
  430. found_slot:
  431. *-------------------------------------------------------*
  432. *    Destroy hash entry                *
  433. *-------------------------------------------------------*
  434.     clr.l        (a2,d2.w*4)
  435.     bra        repair_start
  436. *-------------------------------------------------------*
  437. *    Repair hashtable / re-hash siblings        *
  438. *-------------------------------------------------------*
  439. repair_next:
  440. *-------------------------------------------------------*
  441.     and.w        #chunk_limit-1,d2
  442.     move.l        (a2,d2.w*4),d3
  443.     beq.s        repair_done
  444. *-------------------------------------------------------*
  445. repair_found:
  446. *-------------------------------------------------------*
  447.     move.l        d3,a5
  448. *-------------------------------------------------------*
  449. *    Destroy entry                    *
  450. *-------------------------------------------------------*
  451.     clr.l        (a2,d2.w*4)
  452. *-------------------------------------------------------*
  453. *    Re-hash entry                    *
  454. *-------------------------------------------------------*
  455.     push.l        d2
  456.     move.l        chunk_base(a5),d0
  457.     bsr        hash_address
  458.     lea        (a2,d2.w*4),a4
  459.     move.l        a5,(a4)
  460.     move.l        a4,chunk_slot(a5)
  461.     pop.l        d2
  462. *-------------------------------------------------------*
  463. repair_start:
  464. *-------------------------------------------------------*
  465.     addq.w        #1,d2
  466.     bra.s        repair_next
  467. *-------------------------------------------------------*
  468. repair_done:
  469. *-------------------------------------------------------*
  470.     move.l        chunk_size(a3),d3
  471. *-------------------------------------------------------*
  472. *    Deallocate chunk from 'used' array        *
  473. *-------------------------------------------------------*
  474.     subq.w        #1,used_chunks(a6)
  475.     move.l        chunk_slot(a3),a2
  476.     clr.l        (a2)
  477. *-------------------------------------------------------*
  478. *    Determine defrag rules for neighbours        *
  479. *-------------------------------------------------------*
  480.     move.l        chunk_ln(a3),a2
  481.     move.l        chunk_rn(a3),a4
  482.     tst.b        chunk_lf(a3)
  483.     beq        join_part
  484.     tst.b        chunk_rf(a3)
  485.     beq        join_right
  486. *-------------------------------------------------------*
  487. no_join:
  488. *-------------------------------------------------------*
  489. *    No join possible - flag as free to neighbours    *
  490. *-------------------------------------------------------*
  491.     bclr        #cf_used_bit,chunk_rf(a2)    
  492.     bclr        #cf_used_bit,chunk_lf(a4)    
  493. *-------------------------------------------------------*
  494. *    Append chunk to 'free' array            *
  495. *-------------------------------------------------------*
  496.     move.w        free_chunks(a6),d0
  497.     move.l        free_array(a6),a0
  498.     lea        (a0,d0.w*4),a5
  499.     move.l        a3,(a5)
  500.     move.l        a5,chunk_slot(a3)
  501.     addq.w        #1,d0
  502.     move.w        d0,free_chunks(a6)
  503.     bra        join_done
  504. *-------------------------------------------------------*
  505. join_right:
  506. *-------------------------------------------------------*
  507. *    Expand right neighbour to fill space        *
  508. *-------------------------------------------------------*
  509.     move.l        chunk_size(a3),d0
  510.     add.l        d0,chunk_size(a4)
  511.     move.l        chunk_base(a3),chunk_base(a4)
  512. *-------------------------------------------------------*
  513. *    Unlink chunk from chain                *
  514. *-------------------------------------------------------*
  515.     bsr        unlink_chunk
  516.     bra.s        join_done
  517. *-------------------------------------------------------*
  518. join_left:
  519. *-------------------------------------------------------*
  520. *    Expand left neighbour to fill space        *
  521. *-------------------------------------------------------*
  522.     move.l        chunk_size(a3),d0
  523.     add.l        d0,chunk_size(a2)
  524. *-------------------------------------------------------*
  525. *    Unlink chunk from chain                *
  526. *-------------------------------------------------------*
  527.     bsr        unlink_chunk
  528.     bra.s        join_done
  529. *-------------------------------------------------------*
  530. join_part:
  531. *-------------------------------------------------------*
  532.     tst.b        chunk_rf(a3)
  533.     bne.s        join_left
  534. *-------------------------------------------------------*
  535. join_both:
  536. *-------------------------------------------------------*
  537. *    Expand left neighbour to fill space        *
  538. *-------------------------------------------------------*
  539.     move.l        chunk_size(a3),d0
  540.     add.l        chunk_size(a4),d0
  541.     add.l        d0,chunk_size(a2)
  542. *-------------------------------------------------------*
  543. *    Unlink this chunk from chain            *
  544. *-------------------------------------------------------*
  545.     move.l        chunk_slot(a4),a0        
  546.     bsr        unlink_chunk
  547.     move.l        (a0),a3
  548. *-------------------------------------------------------*
  549. *    Deallocate right neighbour from 'free' array    *
  550. *-------------------------------------------------------*
  551.     move.w        free_chunks(a6),d0
  552.     subq.w        #1,d0
  553.     move.w        d0,free_chunks(a6)
  554.     move.l        free_array(a6),a4
  555.     move.l        (a4,d0.w*4),a2
  556.     clr.l        (a4,d0.w*4)
  557. *-------------------------------------------------------*
  558. *    Seal hole & relocate                *
  559. *-------------------------------------------------------*
  560.     move.l        a2,(a0)
  561.     move.l        a0,chunk_slot(a2)
  562. *-------------------------------------------------------*
  563. *    Unlink right neighbour from chain        *
  564. *-------------------------------------------------------*
  565.     move.l        chunk_ln(a3),a2
  566.     move.l        chunk_rn(a3),a4
  567.     bsr        unlink_chunk
  568. *-------------------------------------------------------*
  569. join_done:
  570. *-------------------------------------------------------*
  571. *    Deallocation was successful            *
  572. *-------------------------------------------------------*
  573.     moveq        #0,d0
  574. *-------------------------------------------------------*
  575. exit:    rts
  576.  
  577. *-------------------------------------------------------*
  578. unlink_chunk:
  579. *-------------------------------------------------------*
  580. *    Maintain neighbour flags            *
  581. *-------------------------------------------------------*
  582.     move.b        chunk_lf(a3),d1
  583.     move.b        chunk_rf(a3),d2
  584.     move.b        d1,d0
  585.     or.b        d2,d0
  586.     and.b        #cf_break,d0
  587.     or.b        d0,d1    
  588.     move.b        d1,chunk_lf(a4)
  589.     or.b        d0,d2    
  590.     move.b        d2,chunk_rf(a2)
  591. *-------------------------------------------------------*
  592. *    Unlink this chunk from chain            *
  593. *-------------------------------------------------------*
  594.     move.l        a4,chunk_rn(a2)
  595.     move.l        a2,chunk_ln(a4)
  596. *-------------------------------------------------------*
  597. *    Remove chunk from chunk array & seal gap    *
  598. *-------------------------------------------------------*
  599.     move.w        total_chunks(a6),d1
  600.     move.l        chunk_array(a6),a2
  601.     subq.w        #1,d1
  602.     move.w        d1,total_chunks(a6)
  603.     mulu.w        #chunk_slen,d1
  604.     add.l        d1,a2
  605.     move.l        a3,a5
  606.     moveq        #0,d7
  607.     moveq        #(chunk_slen/4)-1,d1
  608. .seal:    move.l        (a2),(a5)+
  609.     move.l        d7,(a2)+
  610.     dbra        d1,.seal
  611.     cmp.l        a2,a5
  612.     beq.s        .done
  613. *-------------------------------------------------------*
  614. *    Relocate seal                    *
  615. *-------------------------------------------------------*
  616.     move.l        chunk_ln(a3),a2
  617.     move.l        chunk_rn(a3),a4
  618.     move.l        a3,chunk_rn(a2)
  619.     move.l        a3,chunk_ln(a4)
  620.     move.l        chunk_slot(a3),a2
  621.     move.l        a3,(a2)
  622. .done:    rts
  623.  
  624. *-------------------------------------------------------*
  625. claim_memory:
  626. *-------------------------------------------------------*
  627.     move.l        system_array(a6),a5    
  628.     moveq        #malloc_limit-1,d7
  629.     moveq        #0,d5
  630. *-------------------------------------------------------*
  631. *    Claim loop                    *
  632. *-------------------------------------------------------*
  633. .claim_memory:
  634. *-------------------------------------------------------*
  635. *    Find largest free block                *
  636. *-------------------------------------------------------*
  637.     Mxalloc        #-1,ram_type
  638.     tst.l        d0
  639.     ble.s        .memory_exhausted
  640.     move.l        d0,d6
  641. *-------------------------------------------------------*
  642. *    Attempt to claim that block            *
  643. *-------------------------------------------------------*
  644.     Mxalloc        d0,ram_type
  645.     tst.l        d0
  646.     ble.s        .err
  647. *-------------------------------------------------------*
  648. *    Store block if claim was successful        *
  649. *-------------------------------------------------------*
  650.     move.l        d0,(a5)+
  651.     move.l        d6,(a5)+
  652.     addq.l        #1,d5
  653. *-------------------------------------------------------*
  654. .err:    dbra        d7,.claim_memory
  655. *-------------------------------------------------------*
  656. .memory_exhausted:
  657. *-------------------------------------------------------*
  658.     move.w        d5,system_chunks(a6)
  659.     rts    
  660.  
  661. *-------------------------------------------------------*
  662. init_chunks:
  663. *-------------------------------------------------------*
  664.     moveq        #malloc_base,d0
  665.     bsr        sort_mallocs
  666. *-------------------------------------------------------*
  667. *    Create synthetic chunk for terminating lists    *
  668. *-------------------------------------------------------*
  669.     lea        dummy_lchunk(a6),a1
  670.     lea        dummy_lslot(a6),a2
  671.     lea        dummy_rchunk(a6),a3
  672.     lea        dummy_rslot(a6),a4
  673. *-------------------------------------------------------*
  674. *    Double-link chunk with slot            *
  675. *-------------------------------------------------------*
  676.     move.l        a1,(a2)
  677.     move.l        a2,chunk_slot(a1)
  678.     move.l        a3,(a4)
  679.     move.l        a4,chunk_slot(a3)
  680. *-------------------------------------------------------*
  681.     clr.l        chunk_base(a1)
  682.     clr.l        chunk_size(a1)
  683.     move.b        #cf_break,chunk_lf(a1)
  684.     move.b        #cf_break,chunk_rf(a1)
  685.     clr.w        chunk_flags(a1)
  686.     move.l        #none,chunk_ln(a1)
  687.     move.l        a3,chunk_rn(a1)
  688. *-------------------------------------------------------*
  689.     clr.l        chunk_base(a3)
  690.     clr.l        chunk_size(a3)
  691.     move.b        #cf_break,chunk_lf(a3)
  692.     move.b        #cf_break,chunk_rf(a3)
  693.     clr.w        chunk_flags(a3)
  694.     move.l        a1,chunk_ln(a3)
  695.     move.l        #none,chunk_rn(a3)
  696. *-------------------------------------------------------*
  697.     move.l        free_array(a6),a4
  698.     move.l        chunk_array(a6),a0
  699.     move.l        system_array(a6),a5
  700.     move.l        a0,a1
  701. *-------------------------------------------------------*
  702.     moveq        #0,d6
  703.     move.w        system_chunks(a6),d7
  704.     bra.s        .loops
  705. *-------------------------------------------------------*
  706. .loop:    move.l        malloc_base(a5),d0
  707.     move.l        malloc_size(a5),d1
  708.     add.l        d0,d1
  709.     addq.l        #4-1,d0
  710.     addq.l        #4-1,d1
  711.     and.b        #-4,d0
  712.     and.b        #-4,d1
  713.     sub.l        d0,d1
  714.     cmp.l        #64000,d1
  715.     bmi.s        .cull
  716. *-------------------------------------------------------*
  717. *    Increment free ram counter            *
  718. *-------------------------------------------------------*
  719. ;    add.l        d1,freeram
  720. *-------------------------------------------------------*
  721. *    Create chunk & link to neighbours        *
  722. *-------------------------------------------------------*
  723.     move.l        d0,chunk_base(a0)
  724.     move.l        d1,chunk_size(a0)
  725.     move.b        #cf_break,chunk_lf(a0)
  726.     move.b        #cf_break,chunk_rf(a0)
  727.     move.w        d6,d0
  728.     subq.w        #1,d0
  729.     mulu.w        #chunk_slen,d0
  730.     add.l        a1,d0
  731.     move.l        d0,chunk_ln(a0)
  732.     move.w        d6,d0
  733.     addq.w        #1,d0
  734.     mulu.w        #chunk_slen,d0
  735.     add.l        a1,d0
  736.     move.l        d0,chunk_rn(a0)
  737. *-------------------------------------------------------*
  738. *    Store back-link & increment free count        *
  739. *-------------------------------------------------------*
  740.     move.l        a4,chunk_slot(a0)
  741.     move.l        a0,(a4)+
  742. *-------------------------------------------------------*
  743. *    Advance to next chunk                *
  744. *-------------------------------------------------------*
  745.     lea        chunk_slen(a0),a0
  746.     addq.w        #1,d6
  747. *-------------------------------------------------------*
  748. .cull:    lea        malloc_slen(a5),a5
  749. *-------------------------------------------------------*
  750. .loops:    dbra        d7,.loop
  751. *-------------------------------------------------------*
  752.     move.w        d6,free_chunks(a6)
  753.     move.w        d6,total_chunks(a6)
  754.     beq.s        .err
  755. *-------------------------------------------------------*
  756. *    Link in synthetic [terminator] chunks        *
  757. *-------------------------------------------------------*
  758.     move.l        chunk_array(a6),a0
  759.     move.l        a0,a1
  760.     move.w        free_chunks(a6),d0
  761.     subq.w        #1,d0
  762.     mulu.w        #chunk_slen,d0
  763.     add.l        d0,a1
  764.     lea        dummy_lchunk(a6),a2
  765.     lea        dummy_rchunk(a6),a3
  766.     move.l        a2,chunk_ln(a0)
  767.     move.l        a0,chunk_rn(a2)
  768.     move.l        a3,chunk_rn(a1)
  769.     move.l        a1,chunk_ln(a3)
  770. .err:    rts
  771.  
  772. *-------------------------------------------------------*
  773. sort_mallocs:
  774. *-------------------------------------------------------*
  775.     move.l        system_array(a6),a3
  776.     move.w        system_chunks(a6),d6
  777. *-------------------------------------------------------*
  778. *    Abort sort if entries < 2            *
  779. *-------------------------------------------------------*
  780.     subq.w        #1,d6
  781.     ble.s        .err
  782. *-------------------------------------------------------*
  783.     bra.s        .ogo
  784. *-------------------------------------------------------*
  785. .outer_loop:
  786. *-------------------------------------------------------*
  787.     move.l        a3,a5
  788.     moveq        #0,d4
  789. *-------------------------------------------------------*
  790. *    Inner iterations = entries-1            *
  791. *-------------------------------------------------------*
  792.     move.w        d6,d5
  793.     addq.w        #1,d5
  794.     bra.s        .igo
  795. *-------------------------------------------------------*
  796. .inner_loop:
  797. *-------------------------------------------------------*
  798.     lea        malloc_slen(a5),a4
  799.     move.l        (a5,d0.w),d1
  800.     cmp.l        (a4,d0.w),d1
  801.     ble.s        .no
  802.     moveq        #1,d4
  803.     move.l        malloc_base(a4),d1
  804.     move.l        malloc_base(a5),d2
  805.     move.l        d2,malloc_base(a4)
  806.     move.l        d1,malloc_base(a5)
  807.     move.l        malloc_size(a4),d1
  808.     move.l        malloc_size(a5),d2
  809.     move.l        d2,malloc_size(a4)
  810.     move.l        d1,malloc_size(a5)
  811. .no:    move.l        a4,a5
  812. *-------------------------------------------------------*
  813. .igo:    dbra        d5,.inner_loop
  814. *-------------------------------------------------------*
  815.     tst.l        d4
  816.     beq.s        .err
  817. *-------------------------------------------------------*
  818. .ogo:    dbra        d6,.outer_loop
  819. *-------------------------------------------------------*
  820. .err:    rts
  821.  
  822. *-------------------------------------------------------*
  823. join_mallocs:
  824. *-------------------------------------------------------*    
  825.     moveq        #malloc_base,d0
  826.     bsr        sort_mallocs
  827. *-------------------------------------------------------*
  828.     move.l        system_array(a6),a3
  829.     move.l        a3,a4
  830.     moveq        #0,d2
  831. *-------------------------------------------------------*
  832. *    Iterations = (chunks-1)                *
  833. *-------------------------------------------------------*
  834.     move.w        system_chunks(a6),d6
  835.     subq.w        #1,d6
  836.     ble.s        .err
  837. *-------------------------------------------------------*
  838. *    Index for endmost chunk                *
  839. *-------------------------------------------------------*
  840.     move.w        d6,d7
  841. *-------------------------------------------------------*
  842. *    Start joining chunks                *
  843. *-------------------------------------------------------*
  844.     bra.s        .loops
  845. *-------------------------------------------------------*
  846. *    a4 = current chunk / a5 = next chunk        *
  847. *-------------------------------------------------------*
  848. .loop:    lea        malloc_slen(a4),a5
  849. *-------------------------------------------------------*
  850. *    Check adjacent chunks for contiguity        *
  851. *-------------------------------------------------------*
  852.     move.l        malloc_base(a4),d0
  853.     move.l        malloc_size(a4),d1
  854.     add.l        d1,d0
  855.     cmp.l        malloc_base(a5),d0
  856.     bne.s        .gap
  857. *-------------------------------------------------------*
  858. *    Expand current chunk into next            *
  859. *-------------------------------------------------------*
  860.     add.l        malloc_size(a5),d1
  861.     move.l        d1,malloc_size(a4)
  862. *-------------------------------------------------------*
  863. *    Fill new gap with endmost chunk            *
  864. *-------------------------------------------------------*
  865.     move.l        malloc_base(a3,d7.w*malloc_slen),malloc_base(a5)
  866.     move.l        malloc_size(a3,d7.w*malloc_slen),malloc_size(a5)
  867. *-------------------------------------------------------*
  868. *    Reduce chunk count by #1            *
  869. *-------------------------------------------------------*
  870.     subq.w        #1,system_chunks(a6)
  871. *-------------------------------------------------------*
  872.     bra        join_mallocs
  873. *-------------------------------------------------------*
  874. .gap:    move.l        a5,a4
  875. .loops:    dbra        d6,.loop
  876. *-------------------------------------------------------*
  877. .err:    rts
  878.  
  879. *-------------------------------------------------------*
  880.             bss
  881. *-------------------------------------------------------*
  882.  
  883. os_st_reserve_ptr:    ds.l    1
  884. os_tt_reserve_ptr:    ds.l    1
  885.  
  886. ram_type:        ds.w    1
  887.  
  888. memory_handle:        ds.l    1
  889.  
  890. *-------------------------------------------------------*
  891.  
  892. st_memory_pool:        ds.b    pool_slen
  893.  
  894. st_used_array_space:    ds.l    chunk_limit
  895. st_free_array_space:    ds.l    chunk_limit
  896. st_chunk_array_space:    ds.b    chunk_slen*chunk_limit
  897. st_system_array_space:    ds.b    malloc_slen*malloc_limit
  898.  
  899. *-------------------------------------------------------*
  900.  
  901. tt_memory_pool:        ds.b    pool_slen
  902.  
  903. tt_used_array_space:    ds.l    chunk_limit
  904. tt_free_array_space:    ds.l    chunk_limit
  905. tt_chunk_array_space:    ds.b    chunk_slen*chunk_limit
  906. tt_system_array_space:    ds.b    malloc_slen*malloc_limit
  907.  
  908. *-------------------------------------------------------*
  909.             text
  910. *-------------------------------------------------------*
  911.